package org.myOrg.spetrum.SpecificAlogrithm;

import java.util.Iterator;

import org.myOrg.spetrum.combination.Tuple;
import org.myOrg.spetrum.spectrumStruct.SpectrumFactory;
import org.myOrg.spetrum.spectrumStruct.SpetrumAnalyseBase;
import org.myOrg.spetrum.spectrumStruct.TupleAnalyseStruct;
import org.myOrg.spetrum.testObject.TestSuite;
import org.myOrg.spetrum.testRun.TestRun;

/**
 * @author XinTao Niu
 * 
 */
public class SpectrumAnalyseGreedy extends SpetrumAnalyseBase {
	public final static double POSSIBLECONTAIN = 1.0;
	public final static double MAX = 500000;

	public SpectrumAnalyseGreedy(TestRun run, int[] param,
			TestSuite wrongTestCases, TestSuite rightTestCases) {
		super(run, param, wrongTestCases, rightTestCases);
		this.id = SpectrumFactory.GREEDY;
	}

	public SpectrumAnalyseGreedy() {
		super();
		this.id = SpectrumFactory.GREEDY;
	}

	@Override
	public void init() {
		super.init();
	}

	@Override
	public void setsTructWrong(TupleAnalyseStruct struct) {
		// TODO Auto-generated method stub
		super.setsTructWrong(struct);
		struct.setSuspicion(MAX);
	}

	@Override
	public Tuple getTestTuple() {
		// TODO Auto-generated method stub
		return this.getSusipicionMinmal().getTuple();

	}
	
	@Override
	public void doWrong(Tuple tuple){
		super.doWrong(tuple);
		this.setChildSuspicion(tuple);
	}
	
	public void setChildSuspicion(Tuple tuple){
		TupleAnalyseStruct 	struct = getTupleManager().getTupleAnalyseStructByTuple(tuple);
		Iterator<TupleAnalyseStruct> childs = struct.getAllChilds().iterator();
		while(childs.hasNext()){
			TupleAnalyseStruct child = childs.next();
			child.addSuspicion(POSSIBLECONTAIN);
		}
	}

	/**
	 * this function can be better
	 * 
	 * @param struct
	 * @return
	 */
	public TupleAnalyseStruct getSusipicionMinmal() {
		TupleAnalyseStruct result = null;
		double min = MAX;
		Iterator<TupleAnalyseStruct> itr = getTupleManager().iterator();
		while (itr.hasNext()) {
			TupleAnalyseStruct current = itr.next();
			if(current.isTested())
				continue;
			double temp = possibleLoss(current);
			if ( temp < min) {
				min = temp;
				result = current;
			}
		}
		return result;
	}

	public double possibleLoss(TupleAnalyseStruct struct) {
		double result = 0;
		if (struct.getSuspicion() > result)
			result = struct.getSuspicion();

		Iterator<TupleAnalyseStruct> childs = struct.getAllChilds().iterator();
		double childLoss  = getLoss(childs);
		Iterator<TupleAnalyseStruct> fathers = struct.getAllFathers().iterator();
		double fatherLoss =getLoss(fathers);
		
		return childLoss > fatherLoss ? childLoss : fatherLoss;
	}

	public double getLoss( Iterator<TupleAnalyseStruct> struct) {
		double Loss = 0;
		while (struct.hasNext()) {
			TupleAnalyseStruct child = struct.next();
			if(child.isTested())
				continue;
			else
				Loss++;
		}
		return Loss;
	}
}
